package com.xiangge;
/*
    6.6位运算符【了解】
        分类： &  , |  , ^ , ~ , << , >> , >>>
        引入： 请表示出 5 * 2 的最高效的表示方式
               使用位运算： 将整数值转换成2进制直接进行运算
        明确： 当左右两边是不是boolean类型的结果值或者表达式时,那么就是位运算
        & : 与位运算符
            明确： 二元运算符
                   二进制中： 0代表false , 1 代表true
            特点： 参考逻辑与： 有0则0

       | ： 或位运算符
            明确： 二元运算符
            特点： 参考逻辑或： 有1则1

       ^ : 异或位运算：
            明确： 二元运算符
            特点： 参考逻辑异或： 相同为0,不同为1

            结论： m > 0 , n > 0 , 当 m ^ n ^ n = m  , n ^ m ^ n = m

            作用：
                1. 做加密
                2. 数据交换： int a = 3 , b =5;
       ~ ：非位运算：
           明确： 一元运算符
           特点： 参考逻辑非：非0为1 , 非1为0
           结论： 二进制值的最低位决定了奇偶性     最低位：1 - 奇数    0 - 偶数
                  二进制值的最高位决定了正负性     最高位：1 - 负数    0 - 正数

        << : 左移运算符
           明确： 二元运算符
           特点： 将整数转成二进制,向左边移动指定位数,最低位补0

        >> :右移位运算符
           明确： 二元运算符
           特点： 将整数转成二进制,向右边移动指定位数,最高位补：
                  正整数右移： 最高位补0
                  负整数右移： 最高位补1
        >>> : 无符号右移
            明确： 二元运算符 , 参考右移
            特点： 无论正整数还是负整数最高位都是补0


        结论： m > 0 , n > 0  如果： m << n  --->   m * 2 ^ n
        结论： m > 0 , n > 0  如果： m >> n  --->   m / 2 ^ n

 */
public class OperatorDemo6 {
    public static void main(String[] args) {
        System.out.println(24 >>> 1); // 12 =  24 / 2 ^ 1
        System.out.println(24 >>> 2); // 6 =  24 / 2 ^ 2
        System.out.println(24 >>> 3); // 3 =  24 / 2 ^ 3
        System.out.println(24 >>> 4); // 1 =  24 / 2 ^ 4
    }
    public static void main9(String[] args) {
        System.out.println(10 >>> 1);//5
        System.out.println(-10 >>> 1);//很大的偶数
    }
    public static void main8(String[] args) {
        /*
            12 :0000-0000 0000-0000 0000-0000 0000-1100
          >> 1 : ----------------------------------------
                00000-0000 0000-0000 0000-0000 0000-110

            3 :00000-0000 0000-0000 0000-0000 0000-001
         */
        System.out.println(12 >> 1);
        System.out.println(-10 >> 1); // -5
    }
    public static void main7(String[] args) {
        /*
           << : 左移运算符
             -5 :  1111-1111 1111-1111 1111-1111 1111-1011
             << 1 --------------------------------------------
                  111-1111 1111-1111 1111-1111 1111-10110
         */
        System.out.println(-5 << 1); // -10

    }
    public static void main6(String[] args) {

        /*
           << : 左移运算符
             5 :  0000-0000 0000-0000 0000-0000 0000-0101
             << 1 --------------------------------------------
                  00-0000 0000-0000 0000-0000 0000-01010
         */
        System.out.println(5 << 1); // 10   ==   5 * 2 ^ 1
        System.out.println(5 << 2); // 20   ==   5 * 2 ^ 2
        System.out.println(5 << 3); // 40   ==   5 * 2 ^ 3
        System.out.println(5 << 4); // 80   ==   5 * 2 ^ 4
    }
    public static void main5(String[] args) {
        /*
            9 : 0000-0000 0000-0000 0000-0000 0000-1001
            ~ :  -----------------取反-------------------------------
                1111-1111 1111-1111 1111-1111 1111-0110    10进制： -10
         */
        System.out.println(~9); // -10
    }
    public static void main4(String[] args) {
        int a = 3 , b =5;

        // 使用异或位运算交换a和b的值
        a = a ^ b;
        b = a ^ b;
        a = a ^ b;

        System.out.println("a = " + a + ", b = " + b);//a = 5, b = 3
    }
    public static void main3(String[] args) {

        int password = 123;

        System.out.println(password ^ 3 ^ 678);


        /*
             ^ : 异或位运算：
             特点： 参考逻辑异或： 相同为0,不同为1
             11 :  0000-0000 0000-0000 0000-0000 0000-1011
             5 :   0000-0000 0000-0000 0000-0000 0000-0101
             ^ : ---------------------相同为0,不同为1-------------------------
                   0000-0000 0000-0000 0000-0000 0000-1110  ----> 10进制：14
         */
        System.out.println(11 ^ 5);

        System.out.println(9 ^ 7); //  14
        /*
             9 :  0000-0000 0000-0000 0000-0000 0000-1001
             7 :  0000-0000 0000-0000 0000-0000 0000-0111
             ^ ： ----------------相同为0,不同为1------------------------------
             14   0000-0000 0000-0000 0000-0000 0000-1110     ----> 10进制：14
             7    0000-0000 0000-0000 0000-0000 0000-0111
              ^ ： ----------------相同为0,不同为1------------------------------
                  0000-0000 0000-0000 0000-0000 0000-1001     ------> 10进制：9
         */
        System.out.println(9 ^ 7 ^ 7); // 9
        System.out.println(7 ^ 9 ^ 7); // 9

        System.out.println(999^1^1);
    }
    public static void main2(String[] args) {
        /*
             | ： 或位运算符
             特点： 参考逻辑或： 有1则1
             7 : 0000-0000 0000-0000 0000-0000 0000-0111
             4 : 0000-0000 0000-0000 0000-0000 0000-0100
             | : -----------------有1则1-------------------------
                 0000-0000 0000-0000 0000-0000 0000-0111   ---> 10进制：7
         */
        System.out.println(7 | 4);
       /*
             34 : 0000-0000 0000-0000 0000-0000 0010-0010
             8 :  0000-0000 0000-0000 0000-0000 0000-1000
             | : -----------------有1则1-------------------------
                  0000-0000 0000-0000 0000-0000 0010-1010   ---> 10进制：42
        */
        System.out.println(34 | 8);
    }
    public static void main1(String[] args) {
        /*
             & : 与位运算符
             特点： 参考逻辑与： 有0则0
             7 : 0000-0000 0000-0000 0000-0000 0000-0111
             3 : 0000-0000 0000-0000 0000-0000 0000-0011
             & : ------------有0则0-------------------------
                 0000-0000 0000-0000 0000-0000 0000-0011     ------> 10进制： 3
         */
        System.out.println(7 & 3); // 3

        /*
             16 : 0000-0000 0000-0000 0000-0000 0001-0000
             9 :  0000-0000 0000-0000 0000-0000 0000-1001
             & : ------------有0则0-------------------------
                  0000-0000 0000-0000 0000-0000 0000-0000     ------> 10进制： 0
         */
        System.out.println(16 & 9);// 0
    }
}
